package cn.fastoo.web.api.controller.sys;

import cn.fastoo.common.cache.Price;
import cn.fastoo.common.dao.FastooMtDetailDao;
import cn.fastoo.common.dao.SmsrecordDao;
import cn.fastoo.common.entity.FastooMtDetail;
import cn.fastoo.common.entity.UserBase;
import cn.fastoo.common.sampleframe.dto.JsonResult;
import cn.fastoo.common.sampleframe.search.Search;
import cn.fastoo.common.utils.*;
import cn.fastoo.service.JdbcTemplateService;
import cn.fastoo.service.UserService;
import cn.fastoo.task.DrMessage;
import cn.fastoo.task.DrQueue;
import cn.fastoo.task.MtMessage;
import cn.fastoo.task.SantoMtMessageQueue;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by hp on 2017/8/10.
 */
@Controller
@RequestMapping("/v1")
public class ApiController {

    private final static Logger logger = LoggerFactory.getLogger(ApiController.class);

    @Autowired
    private SmsrecordDao smsrecordDao;
    @Autowired
    private FastooMtDetailDao fastooMtDetailDao;
    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private JdbcTemplateService jdbcTemplateService;


    /**
     * api提交
     */
    @RequestMapping("submit")
    @ResponseBody
    public String submit(HttpServletRequest request,@RequestParam String apikey, @RequestParam String da, @RequestParam String msg){
        JSONObject jsonObject = new JSONObject();
        String requestIp = StringUtil.getIpAddr(request);

        if (Strings.isNullOrEmpty(apikey) || Strings.isNullOrEmpty(da) || Strings.isNullOrEmpty(msg)) {
            logger.error("["+apikey+"]请求参数错误");
            return new JsonResult(400,"请求参数错误").toJson();
        }

        try {
            msg = URLDecoder.decode(msg,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return new JsonResult(600,"系统异常").toJson();
        }

        // apiKey验证
        final UserBase userBase = jdbcTemplateService.getUserBase(apikey);
        if (userBase==null) {
            logger.error("["+apikey+"]没有此用户");
            return new JsonResult(101,"没有此用户").toJson();
        }

        //账户余额不足
        if (userBase.getBalance()<=0) {
            logger.error("["+apikey+"]金额不足");
            return new JsonResult(200,"金额不足").toJson();
        }

        //白名单IP
        if (userBase.getIpEnable()==1) {
            List<String> iplist = jdbcTemplateService.getIpList(userBase.getId());
            if (iplist != null && iplist.size() > 0) {
                if (!iplist.contains(requestIp)) {
                    logger.error("["+apikey+"]非法IP地址访问");
                    return new JsonResult(203, "非法IP地址访问").toJson();
                }
            } else {
                logger.error("["+apikey+"]非法IP地址访问");
                return new JsonResult(203, "非法IP地址访问").toJson();
            }
        }

        // 验证目标号码
        String[] daArry = da.split(","); // 多个号码用逗号分隔
        if (daArry.length > 100) {
            logger.error("["+apikey+"]请求ip:" + requestIp + ",目标地址超过100个！ destAddr:" + da);
            return new JsonResult(203, "非法IP地址访问").toJson();
        }
        String checkStr = "";
        for (String daStar : daArry) { // 目标号码格式有错
            String dest = daStar.replace("-", "").replace("+", "");
            dest = dest.replace(" ", "");
            dest = dest.replaceFirst("^0+(?!$)", "");

            if (!PhoneNumberUtils.isValidNumber(dest) || dest.length() > 15) {
                if (dest.length() > 6) {
//                    .save(userBase.getId(),apikey,, dest, msg);
                }
                logger.error("请求ip:" + requestIp + "目标地址错误！[" + apikey + "] destAddr:" + da);
            } else {
                checkStr += dest + ",";

                //模板验证
                String countryCode = PhoneNumberUtils.getCountryCode(dest);
                if (!Strings.isNullOrEmpty(countryCode) && "CN".equals(countryCode)) {
                    //如果用户提交的是系统模板，则不需要验证直接通过
                    if(!RegexUtils.match(msg,"您的验证码是@")){
                        boolean pass = jdbcTemplateService.verifyTemplate(apikey, msg);
                        logger.info("["+apikey+"]请求ip:" + requestIp + ",msg="+msg+",pass="+pass);
                        if (!pass) {
                            return new JsonResult(204, "模板不匹配").toJson();
                        }
                    }
                }
            }
        }

        if (checkStr.length() > 0 && checkStr.indexOf(",") > 0) {
            checkStr = checkStr.substring(0, checkStr.length() - 1);
        }
        if(checkStr.length() <= 0) {
            return new JsonResult(205, "下发号码无效").toJson();
        }


        // 自定义Sender

        final String fastooMsgid = MessageHelper.getSequenceId(new Date().getTime());


        final String apiKey = apikey;
        final String destAddrs = checkStr;
        final String message = msg;


        new Thread(){
            @Override
            public void run() {
                String[] daArr = destAddrs.split(",");
                for (String da : daArr) {
                    //短信计费条数
                    String contryCode = PhoneNumberUtils.getCountryCode(da);
                    String signName = userBase.getSignName();
                    Integer smsize = MessageHelper.getSmsLength(message,contryCode,signName);
                    Price price = PriceUtil.load(jdbcTemplate, apiKey, contryCode);

                    FastooMtDetail mtDetail = new FastooMtDetail();
                    mtDetail.setLoginName(userBase.getLoginName());
                    mtDetail.setFastooMsgid(fastooMsgid);
                    mtDetail.setApiKey(apiKey);
                    mtDetail.setMsgContent(message);
                    mtDetail.setDestAddr(da);
                    mtDetail.setCountryCode(contryCode);
                    mtDetail.setPrice(price.getMtPrice());
                    mtDetail.setFeeCount(smsize);
                    if (userBase.getNeedDr()==1) {
                        mtDetail.setDrUrl(userBase.getDrUrl());
                    }
                    fastooMtDetailDao.insert(mtDetail);

                    MtMessage mtMessage = new MtMessage();
                    mtMessage.setDa(da);
                    mtMessage.setFastooMsgid(fastooMsgid);
                    mtMessage.setMsg(message);
                    SantoMtMessageQueue.put(userService,mtMessage);
                }
            }
        }.start();

        jsonObject.put("msgid",fastooMsgid);
        return new JsonResult(0,"提交成功",jsonObject).toJson();
    }




    /**
     * 接收状态报告
     */
    @RequestMapping("dr")
    @ResponseBody
    public String dr(@RequestParam String msgid,@RequestParam String da,@RequestParam String rsm) {
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isBlank(msgid) || StringUtils.isBlank(da) || StringUtils.isBlank(rsm)) {
            return  JsonResult.create(400,"非法参数");
        }

        logger.info("response status report santoChannelMsgid=" + msgid + ",da=" + da + ",rsm=" + rsm);

        FastooMtDetail mtDetail = fastooMtDetailDao.findOne(new Search().addSearchFilter("EQ_santoChannelMsgid",msgid).addSearchFilter("EQ_destAddr",da));
        if (mtDetail!=null) {
            try {
                // rsm=14277266615330590|0|DELIVRD||
                // rsm=14277266615330590|400|404||
                String smstr = URLDecoder.decode(rsm,"UTF-8");

                int idx = smstr.indexOf("||");
                if (idx > 0) {
                    smstr = smstr.substring(0, idx);
                }

                int stat = 1;
                // 报告成功
                if (smstr.indexOf("DELIVRD") > -1) {
                    mtDetail.setDrStatus(1);
                    mtDetail.setDrStatuscode("DELIVRD");
                } else {
                    stat = 0;
                    String status = smstr.substring(smstr.indexOf("|") + 1, smstr.lastIndexOf("|"));
                    String statusCode = smstr.substring(smstr.lastIndexOf("|") + 1);
                    mtDetail.setDrStatus(2);
                    mtDetail.setDrStatuscode(statusCode);
                }

                mtDetail.setDrTime(new Date());
                fastooMtDetailDao.update(mtDetail);

                //更新smsrecord报告
                jdbcTemplateService.updateSmsrecordDrStatus(mtDetail.getFastooMsgid(),da,mtDetail.getDrStatus(),mtDetail.getDrStatuscode());

                //推送报告
                if (StringUtils.isNotBlank(mtDetail.getDrUrl())) {
                    reportDr(mtDetail.getFastooMsgid(),da,stat,mtDetail.getDrUrl());
                }

            } catch (Exception e) {
                e.printStackTrace();
                return  JsonResult.create(400,"接收异常");
            }
        }

        return new JsonResult(0,"ok",jsonObject).toJson();
    }

    private void reportDr(String fastooMsgid, String da, int stat, String drUrl) {
        DrMessage drMessage = new DrMessage();
        drMessage.setDa(da);
        drMessage.setStatus(stat);
        drMessage.setFastooMsgid(fastooMsgid);
        drMessage.setDrUrl(drUrl);
        DrQueue.put(drMessage);
    }


}
